<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>珠峰培训零基础高薪就业班</title>
</head>

<body>
  <script>
    const isPlainObject = function isPlainObject(obj) {
      let proto, Ctor;
      if (!obj || Object.prototype.toString.call(obj) !== "[object Object]") return false;
      proto = Object.getPrototypeOf(obj);
      if (!proto) return true;
      Ctor = proto.hasOwnProperty('constructor') && proto.constructor;
      return typeof Ctor === "function" && Ctor === Object;
    };

    let data = {
      x: 1,
      y: {
        n: 2,
        m: 3,
        k: [100, 20]
      },
      z: [10, 20, 30]
    };

    // proxy就是data的劫持对象，我们以后要操作的是proxy
    let proxy = new Proxy(data, {
      get(target, key) {
        console.log('GETTER');
        return target[key];
      },
      set(target, key, value) {
        console.log('SETTER');
        target[key] = value;
      },
      deleteProperty(target, key) {
        console.log('DELETE');
        return Reflect.deleteProperty(target, key);
      }
    });


    /*
    Vue3中的响应式原理：
      @1 以ref为主的get/set劫持「核心还是Object.defineProperty」
      @2 以reacive为主的数据劫持，是基于ES6中的Proxy实现的
      特点：
      + 直接对整个对象进行代理劫持,而且对于数组每一项也是直接劫持 -> Vue3的响应式性能/易操作上要强于Vue2
      + 除了做get/set劫持外，还可以实现其它方面的劫持：getPrototypeOf/setPrototypeOf/isExtensible/preventExtensions/getOwnPropertyDescriptor/defineProperty/has/deleteProperty/ownKeys/apply/construct，Vue3中实现了get/set/deleteProperty/has/ownKeys等劫持 -> Vue3响应式实现的功能要强于Vue2
      + 也像Vue2一样，基于递归对“对象”做了深层次劫持
      + ES6新增的API，不兼容IE
   */

    /*
     Vue2中的响应式原理：
       + 首先对data进行深度的监听和劫持  Object.defineProperty「ES5」
       + 对数组每一项不进行处理，而是重写了数组的原型指向「push/pop/shift/unshift/splice/sort/reverse」
       特点：
       + 对“对象”中的每一项只做了get/set的劫持，只有获取及修改属性值的时候，才会触发劫持函数
       + 依次迭代对象中的每个属性，给每个属性分别做劫持
       + 对于数组每一项只是重写了原型对象，但是没有做劫持
         obj.z=[...]  视图会更新
         obj.z[0]=100 视图不会更新
         obj.z.splice(0,1,100) 视图会更新
       + 基于递归把每一次层级都做了劫持
       + ES5劫持方法，所以兼容IE9+「Vue2可以兼容IE9+」
       + 如果当前对象是被冻结的，则不进行劫持处理
     */
  </script>
</body>

</html>